package com.zym.init.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.zym.init.annotation.RoleCheck;
import com.zym.init.constant.RoleConstant;
import com.zym.init.core.controller.BaseController;
import com.zym.init.core.domain.AjaxResult;
import com.zym.init.enums.UserStatusEnum;
import com.zym.init.exception.BannedException;
import com.zym.init.model.domain.User;
import com.zym.init.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 用户控制器
 *
 * @author ZouYangMing
 */
@RestController
@RequestMapping(path = "/user", produces = "application/json")
@Tag(name = "01 用户", description = "API")
@ApiResponse(responseCode = "0", description = "成功")
public class UserController extends BaseController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /**
     * 获取当前登录用户信息
     *
     * @return AjaxResult对象
     */
    @GetMapping("/getLoginUser")
    @Operation(summary = "获取当前登录用户信息")
    public AjaxResult getLoginUser() {
        return success(userService.selectUserVoById(StpUtil.getLoginIdAsLong()));
    }

    /**
     * 注册
     */
    @PostMapping("/register")
    @Operation(summary = "注册新用户")
    public AjaxResult register(@RequestBody User user) {
        if (userService.insertUser(user)) {
            return success("注册成功");
        }
        return error("注册失败，请联系管理员");
    }

    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     * @return AjaxResult对象
     */
    @GetMapping("/doLogin")
    @Operation(summary = "用户登录")
    public AjaxResult doLogin(
            @Parameter(description = "用户名", required = true, example = "123456") String username,
            @Parameter(description = "密码", required = true, example = "123456") String password) {
        if (StpUtil.isLogin()) {
            return warn("您已登录");
        }

        User user = userService.selectUserByUsernameAndPassword(username, password);

        // 检查账号是否已被封禁
        UserStatusEnum enumByStatus = UserStatusEnum.getEnumByStatus(user.getStatus());
        if (enumByStatus == UserStatusEnum.BANNED) {
            // 踢出登录
            StpUtil.logout();
            // 抛出封禁异常
            throw new BannedException();
        } else if (enumByStatus == UserStatusEnum.SUSPENDED) {
            // 踢出登录
            StpUtil.logout();
            // 获取当前时间距离解封时间的秒数
            long suspendedTime = DateUtil.between(DateUtil.date(), user.getSuspendedTime(), DateUnit.MINUTE);
            // 抛出异常
            throw new BannedException("账号已被封禁，距离解封还有：" + suspendedTime + "分钟");
        }

        // 登录
        StpUtil.login(user.getUserId());

        // 更新用户最后登录时间
        userService.updateUserLastLoginTime(user.getUserId());

        return success("登录成功", Map.of("token", StpUtil.getTokenValue()));
    }

    /**
     * 检查是否登录
     *
     * @return AjaxResult对象
     */
    @GetMapping("/isLogin")
    @Operation(summary = "检查是否登录")
    public AjaxResult isLogin() {
        return success(StpUtil.isLogin());
    }

    /**
     * 注销
     *
     * @return AjaxResult对象
     */
    @GetMapping("/logout")
    @Operation(summary = "注销")
    public AjaxResult logout() {
        StpUtil.logout();
        return success();
    }

    /**
     * 管理员权限测试
     */
    @RoleCheck(role = RoleConstant.ROLE_ADMIN)
    @GetMapping("/isAdmin")
    @Operation(summary = "管理员权限测试")
    public AjaxResult isAdmin() {
        return success("管理员权限测试");
    }

    /**
     * 用户权限测试
     */
    @RoleCheck(role = RoleConstant.ROLE_USER)
    @GetMapping("/isUser")
    @Operation(summary = "用户权限测试")
    public AjaxResult isUser() {
        return success("用户权限测试");
    }
}
